package org.example.springbirthday.controller;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.example.springbirthday.config.CaptchaProperties;
import org.example.springbirthday.constants.Constants;
import org.example.springbirthday.model.Result;
import org.example.springbirthday.model.UserInfo;
import org.example.springbirthday.service.UserService;
import org.example.springbirthday.utils.JwtUtils;
import org.example.springbirthday.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 九转苍翎
 * Date: 2025/8/7
 * Time: 01:55
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private CaptchaProperties captchaProperties;

    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public Result<String> login(String userName, String password,String input, HttpSession session){
        log.info("登录,userName:{},password:{},input:{}",userName,password,input);
        //1.参数校验合法性
        if (!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)){
            return Result.fail("用户或密码为空");
        }
        //2.从数据库中查找用户
        UserInfo userByName = userService.getUserByName(userName);
        if (userByName == null){
            return Result.fail("用户不存在");
        }
        //3.校验密码是否正确
        if (!SecurityUtils.verify(password,userByName.getPassword())){
            return Result.fail("密码错误");
        }
        //4.校验验证码
        if (!StringUtils.hasLength(input)) {
            return Result.fail("验证码为空");
        }
        long savedDate = (long)session.getAttribute(captchaProperties.getSession().getDate());
        long curDate = System.currentTimeMillis();
        if (curDate - savedDate > CaptchaController.delay) {
            return Result.fail("验证码超时");
        }
        String savedCode = (String)session.getAttribute(captchaProperties.getSession().getKey());
        if(!savedCode.equalsIgnoreCase(input)){
            return Result.fail("验证码错误");
        }
        //5.生成token
        Map<String,Object> map = new HashMap<>();
        map.put(Constants.TOKEN_ID,userByName.getId());
        map.put(Constants.TOKEN_USERNAME,userByName.getUserName());
        String token = JwtUtils.generateToken(map);
        log.info("登录完成,生成token:{}",token);
        return Result.success(token);
    }

    @RequestMapping("/register")
    public Result<String> register(String userName,String password){
        log.info("注册,userName:{},password:{}",userName,password);
        //1.参数校验合法性
        if (!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)){
            return Result.fail("用户或密码为空");
        }
        try {
            //处理密码
            String encryptPassword = SecurityUtils.encrypt(password);
            Integer ret = userService.register(userName, encryptPassword);
            if (ret == 1) {
                return Result.success("注册成功");
            }
        }catch (Exception e){
            log.error("该用户名已存在,e",e);
        }
        return Result.fail("该用户名已存在");
    }

    @RequestMapping("/getLoginUser")
    public UserInfo getLoginUser(HttpServletRequest request){
        String token = request.getHeader(Constants.REQUEST_HEADER_TOKEN);
        log.info("获取当前登录用户,解析token:{}",token);
        Integer userId = JwtUtils.getIdByToken(token);
        log.info("获取当前登录用户,解析userId:{}",userId);
        return userService.getUserById(userId);
    }

    @RequestMapping("/getUserInfoList")
    public List<UserInfo> getUserInfoList(Integer page,Integer size){
        log.info("获取用户列表,接收到参数,page:{},size:{}",page,size);
        return userService.getUserInfoListByPageAndSize((page - 1) * size,size);
    }

    @RequestMapping("/isBirthday")
    public List<UserInfo> isBirthday(){
        return userService.isBirthday();
    }

    @RequestMapping("/cancel")
    public Result<String> cancel(HttpServletRequest request){
        String token = request.getHeader(Constants.REQUEST_HEADER_TOKEN);
        log.info("注销用户,解析token:{}",token);
        Integer userId = JwtUtils.getIdByToken(token);
        try {
            Integer ret = userService.cancel(userId);
            if (ret == 2) {
                return Result.success("注销成功");
            }
        }catch (Exception e){
            log.error("注销失败");
        }
        return Result.fail("注销失败");
    }

    @RequestMapping("update")
    public Result<String> update(UserInfo userInfo,HttpServletRequest request){
        log.info("修改用户信息,userInfo:{}",userInfo);
        String token = request.getHeader(Constants.REQUEST_HEADER_TOKEN);
        log.info("修改用户信息,解析token:{}",token);
        Integer userId = JwtUtils.getIdByToken(token);
        log.info("修改用户信息,解析userId:{}",userId);
        userInfo.setPassword(SecurityUtils.encrypt(userInfo.getPassword()));
        userInfo.setId(userId);
        try {
            Integer ret = userService.update(userInfo);
            if (ret == 1) {
                return Result.success("修改用户信息成功");
            }
        }catch (Exception e){
            log.error("修改用户信息失败,e",e);
        }
        return Result.fail("该用户名已存在");
    }

    @RequestMapping("/upload")
    public Result<String> upload(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws IOException {
        if (file.isEmpty()) {
            return Result.fail("文件为空");
        }
        log.info("上传文件,file:{}", file.getOriginalFilename());
        String token = request.getHeader(Constants.REQUEST_HEADER_TOKEN);
        log.info("上传文件,解析token:{}",token);
        Integer userId = JwtUtils.getIdByToken(token);
        log.info("上传文件,解析userId:{}",userId);
        UserInfo userInfo = userService.getUserById(userId);
        userInfo.setFile(file.getBytes());
        try {
            Integer ret = userService.save(userInfo);
            if (ret == 1) {
                return Result.success("文件上传成功");
            }
        }catch (Exception e){
            log.error("文件上传失败,e",e);
        }
        return Result.fail("文件过大");
    }

    @RequestMapping("/download")
    public ResponseEntity<StreamingResponseBody> downloadFile(HttpServletRequest request) {
        //1.userId
        String token = request.getHeader(Constants.REQUEST_HEADER_TOKEN);
        log.info("下载文件,解析token:{}", token);
        Integer userId = JwtUtils.getIdByToken(token);
        log.info("根据当前登录用户的id下载文件,userId:{}", userId);
        return downloadCommon(userId);
    }

    @RequestMapping("/downloadById")
    public ResponseEntity<StreamingResponseBody> downloadById(Integer id) {
        log.info("根据提供的用户id下载文件,userId:{}", id);
        return downloadCommon(id);
    }

    private ResponseEntity<StreamingResponseBody> downloadCommon(Integer userId){
        //1.获取文件流
        InputStream fileStream = userService.getFileById(userId);
        if (fileStream == null) {
            return ResponseEntity.notFound().build();
        }
        //3.构建流式响应
        StreamingResponseBody responseBody = outputStream -> {
            try (fileStream) {
                fileStream.transferTo(outputStream);
            }
        };
        return ResponseEntity.ok().body(responseBody);
    }
}
